#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Git Hooks 动态配置系统 - 配置管理工具
负责管理配置文件
"""

import os
import sys
import argparse
import yaml
import json
from pathlib import Path
from typing import Dict, List, Any, Optional

# 添加项目根目录到 Python 路径
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))

from core.config_parser import ConfigParser, ConfigValidator


class ConfigManager:
    """配置管理器"""
    
    def __init__(self):
        self.project_root = Path(__file__).parent.parent
        self.config_dir = self.project_root / 'config'
        self.config_file = self.config_dir / 'hooks.yaml'
        self.logger = self._setup_logger()
    
    def _setup_logger(self):
        """设置日志"""
        import logging
        logger = logging.getLogger(__name__)
        logger.setLevel(logging.INFO)
        
        # 控制台处理器
        handler = logging.StreamHandler()
        formatter = logging.Formatter('%(levelname)s: %(message)s')
        handler.setFormatter(formatter)
        logger.addHandler(handler)
        
        return logger
    
    def show_config(self, hook_name: str = None) -> bool:
        """显示配置"""
        try:
            parser = ConfigParser(str(self.config_dir))
            config = parser.load_config()
            
            if hook_name:
                # 显示特定 Hook 配置
                hook_config = parser.get_hook_config(hook_name)
                if not hook_config:
                    self.logger.error(f"未找到 Hook 配置: {hook_name}")
                    return False
                
                print(f"\nHook 配置: {hook_name}")
                print("="*50)
                print(f"启用状态: {'是' if hook_config.enabled else '否'}")
                print(f"描述: {hook_config.description}")
                print(f"任务数量: {len(hook_config.tasks)}")
                
                for i, task in enumerate(hook_config.tasks, 1):
                    print(f"\n任务 {i}: {task.name}")
                    print(f"  类型: {task.type.value}")
                    print(f"  启用: {'是' if task.enabled else '否'}")
                    print(f"  并行: {'是' if task.parallel else '否'}")
                    if task.timeout:
                        print(f"  超时: {task.timeout}s")
                    if task.retry_count:
                        print(f"  重试次数: {task.retry_count}")
                    if task.conditions:
                        print(f"  条件数量: {len(task.conditions)}")
                
            else:
                # 显示全局配置
                global_config = parser.get_global_config()
                if not global_config:
                    self.logger.error("无法加载全局配置")
                    return False
                
                print("\n全局配置:")
                print("="*50)
                print(f"启用状态: {'是' if global_config.enabled else '否'}")
                print(f"日志级别: {global_config.log_level.value}")
                print(f"日志文件: {global_config.log_file}")
                print(f"快速失败: {'是' if global_config.fail_fast else '否'}")
                print(f"最大并行任务: {global_config.max_parallel_tasks}")
                
                # 显示所有 Hook
                hooks_config = config.get('hooks', {})
                print(f"\n已配置的 Hook ({len(hooks_config)} 个):")
                for hook_name, hook_config in hooks_config.items():
                    enabled = hook_config.get('enabled', True)
                    task_count = len(hook_config.get('tasks', []))
                    print(f"  - {hook_name}: {'启用' if enabled else '禁用'} ({task_count} 个任务)")
            
            return True
            
        except Exception as e:
            self.logger.error(f"显示配置失败: {e}")
            return False
    
    def validate_config(self) -> bool:
        """验证配置"""
        try:
            parser = ConfigParser(str(self.config_dir))
            config = parser.load_config()
            
            # 验证配置格式
            errors = parser.validate_config(config)
            
            if errors:
                self.logger.error("配置验证失败:")
                for error in errors:
                    self.logger.error(f"  - {error}")
                return False
            else:
                self.logger.info("配置验证通过")
                return True
                
        except Exception as e:
            self.logger.error(f"验证配置失败: {e}")
            return False
    
    def enable_hook(self, hook_name: str) -> bool:
        """启用 Hook"""
        try:
            if not self.config_file.exists():
                self.logger.error("配置文件不存在")
                return False
            
            # 读取配置
            with open(self.config_file, 'r', encoding='utf-8') as f:
                config = yaml.safe_load(f)
            
            # 更新配置
            if 'hooks' not in config:
                config['hooks'] = {}
            
            if hook_name not in config['hooks']:
                config['hooks'][hook_name] = {}
            
            config['hooks'][hook_name]['enabled'] = True
            
            # 保存配置
            with open(self.config_file, 'w', encoding='utf-8') as f:
                yaml.dump(config, f, default_flow_style=False, allow_unicode=True)
            
            self.logger.info(f"已启用 Hook: {hook_name}")
            return True
            
        except Exception as e:
            self.logger.error(f"启用 Hook 失败: {e}")
            return False
    
    def disable_hook(self, hook_name: str) -> bool:
        """禁用 Hook"""
        try:
            if not self.config_file.exists():
                self.logger.error("配置文件不存在")
                return False
            
            # 读取配置
            with open(self.config_file, 'r', encoding='utf-8') as f:
                config = yaml.safe_load(f)
            
            # 更新配置
            if 'hooks' not in config:
                config['hooks'] = {}
            
            if hook_name not in config['hooks']:
                config['hooks'][hook_name] = {}
            
            config['hooks'][hook_name]['enabled'] = False
            
            # 保存配置
            with open(self.config_file, 'w', encoding='utf-8') as f:
                yaml.dump(config, f, default_flow_style=False, allow_unicode=True)
            
            self.logger.info(f"已禁用 Hook: {hook_name}")
            return True
            
        except Exception as e:
            self.logger.error(f"禁用 Hook 失败: {e}")
            return False
    
    def add_task(self, hook_name: str, task_config: Dict[str, Any]) -> bool:
        """添加任务"""
        try:
            if not self.config_file.exists():
                self.logger.error("配置文件不存在")
                return False
            
            # 读取配置
            with open(self.config_file, 'r', encoding='utf-8') as f:
                config = yaml.safe_load(f)
            
            # 更新配置
            if 'hooks' not in config:
                config['hooks'] = {}
            
            if hook_name not in config['hooks']:
                config['hooks'][hook_name] = {'enabled': True, 'tasks': []}
            
            if 'tasks' not in config['hooks'][hook_name]:
                config['hooks'][hook_name]['tasks'] = []
            
            config['hooks'][hook_name]['tasks'].append(task_config)
            
            # 保存配置
            with open(self.config_file, 'w', encoding='utf-8') as f:
                yaml.dump(config, f, default_flow_style=False, allow_unicode=True)
            
            self.logger.info(f"已添加任务到 Hook: {hook_name}")
            return True
            
        except Exception as e:
            self.logger.error(f"添加任务失败: {e}")
            return False
    
    def remove_task(self, hook_name: str, task_name: str) -> bool:
        """移除任务"""
        try:
            if not self.config_file.exists():
                self.logger.error("配置文件不存在")
                return False
            
            # 读取配置
            with open(self.config_file, 'r', encoding='utf-8') as f:
                config = yaml.safe_load(f)
            
            # 更新配置
            if 'hooks' not in config or hook_name not in config['hooks']:
                self.logger.error(f"Hook 不存在: {hook_name}")
                return False
            
            tasks = config['hooks'][hook_name].get('tasks', [])
            original_count = len(tasks)
            
            # 移除任务
            config['hooks'][hook_name]['tasks'] = [
                task for task in tasks if task.get('name') != task_name
            ]
            
            removed_count = original_count - len(config['hooks'][hook_name]['tasks'])
            
            if removed_count == 0:
                self.logger.warning(f"未找到任务: {task_name}")
                return False
            
            # 保存配置
            with open(self.config_file, 'w', encoding='utf-8') as f:
                yaml.dump(config, f, default_flow_style=False, allow_unicode=True)
            
            self.logger.info(f"已移除任务: {task_name} (从 {hook_name})")

            
            return True
            
        except Exception as e:
            self.logger.error(f"移除任务失败: {e}")
            return False
    
    def set_global_config(self, key: str, value: Any) -> bool:
        """设置全局配置"""
        try:
            if not self.config_file.exists():
                self.logger.error("配置文件不存在")
                return False
            
            # 读取配置
            with open(self.config_file, 'r', encoding='utf-8') as f:
                config = yaml.safe_load(f)
            
            # 更新配置
            if 'global' not in config:
                config['global'] = {}
            
            config['global'][key] = value
            
            # 保存配置
            with open(self.config_file, 'w', encoding='utf-8') as f:
                yaml.dump(config, f, default_flow_style=False, allow_unicode=True)
            
            self.logger.info(f"已设置全局配置: {key} = {value}")
            return True
            
        except Exception as e:
            self.logger.error(f"设置全局配置失败: {e}")
            return False
    
    def export_config(self, output_file: str) -> bool:
        """导出配置"""
        try:
            if not self.config_file.exists():
                self.logger.error("配置文件不存在")
                return False
            
            # 读取配置
            with open(self.config_file, 'r', encoding='utf-8') as f:
                config = yaml.safe_load(f)
            
            # 导出配置
            output_path = Path(output_file)
            if output_path.suffix == '.json':
                with open(output_path, 'w', encoding='utf-8') as f:
                    json.dump(config, f, indent=2, ensure_ascii=False)
            else:
                with open(output_path, 'w', encoding='utf-8') as f:
                    yaml.dump(config, f, default_flow_style=False, allow_unicode=True)
            
            self.logger.info(f"配置已导出到: {output_file}")
            return True
            
        except Exception as e:
            self.logger.error(f"导出配置失败: {e}")
            return False
    
    def import_config(self, input_file: str) -> bool:
        """导入配置"""
        try:
            input_path = Path(input_file)
            if not input_path.exists():
                self.logger.error(f"配置文件不存在: {input_file}")
                return False
            
            # 读取配置
            with open(input_path, 'r', encoding='utf-8') as f:
                if input_path.suffix == '.json':
                    config = json.load(f)
                else:
                    config = yaml.safe_load(f)
            
            # 验证配置
            parser = ConfigParser(str(self.config_dir))
            errors = parser.validate_config(config)
            if errors:
                self.logger.error("配置验证失败:")
                for error in errors:
                    self.logger.error(f"  - {error}")
                return False
            
            # 保存配置
            with open(self.config_file, 'w', encoding='utf-8') as f:
                yaml.dump(config, f, default_flow_style=False, allow_unicode=True)
            
            self.logger.info(f"配置已导入从: {input_file}")
            return True
            
        except Exception as e:
            self.logger.error(f"导入配置失败: {e}")
            return False
    
    def create_template(self, template_name: str) -> bool:
        """创建配置模板"""
        templates = {
            'basic': {
                'global': {
                    'enabled': True,
                    'log_level': 'info',
                    'fail_fast': True
                },
                'hooks': {
                    'pre-commit': {
                        'enabled': True,
                        'description': '提交前检查',
                        'tasks': [
                            {
                                'name': '代码格式检查',
                                'type': 'lint',
                                'config': {
                                    'tools': ['eslint'],
                                    'files': ['*.js', '*.ts']
                                },
                                'parallel': True
                            }
                        ]
                    }
                }
            },
            'advanced': {
                'global': {
                    'enabled': True,
                    'log_level': 'info',
                    'fail_fast': True,
                    'max_parallel_tasks': 4
                },
                'hooks': {
                    'pre-commit': {
                        'enabled': True,
                        'description': '提交前检查',
                        'tasks': [
                            {
                                'name': '代码格式检查',
                                'type': 'lint',
                                'config': {
                                    'tools': ['eslint', 'prettier'],
                                    'files': ['*.js', '*.ts', '*.jsx', '*.tsx']
                                },
                                'conditions': [
                                    {
                                        'type': 'file_pattern',
                                        'pattern': '*.{js,ts,jsx,tsx}'
                                    }
                                ],
                                'parallel': True
                            },
                            {
                                'name': '安全检查',
                                'type': 'security',
                                'config': {
                                    'tools': ['npm-audit']
                                },
                                'conditions': [
                                    {
                                        'type': 'file_exists',
                                        'file': 'package.json'
                                    }
                                ],
                                'parallel': True
                            }
                        ]
                    },
                    'commit-msg': {
                        'enabled': True,
                        'description': '提交信息验证',
                        'tasks': [
                            {
                                'name': '提交信息格式检查',
                                'type': 'commit-msg-validator',
                                'config': {
                                    'pattern': '^(feat|fix|docs|style|refactor|test|chore)(\\(.+\\))?: .{1,50}',
                                    'min_length': 10,
                                    'max_length': 100
                                }
                            }
                        ]
                    }
                }
            }
        }
        
        if template_name not in templates:
            self.logger.error(f"未知模板: {template_name}")
            self.logger.info(f"可用模板: {', '.join(templates.keys())}")
            return False
        
        try:
            # 创建配置目录
            self.config_dir.mkdir(parents=True, exist_ok=True)
            
            # 保存模板
            template_config = templates[template_name]
            with open(self.config_file, 'w', encoding='utf-8') as f:
                yaml.dump(template_config, f, default_flow_style=False, allow_unicode=True)
            
            self.logger.info(f"已创建模板: {template_name}")
            return True
            
        except Exception as e:
            self.logger.error(f"创建模板失败: {e}")
            return False


def main():
    """主函数"""
    parser = argparse.ArgumentParser(description='Git Hooks 动态配置系统配置管理工具')
    
    subparsers = parser.add_subparsers(dest='command', help='可用命令')
    
    # 显示配置
    show_parser = subparsers.add_parser('show', help='显示配置')
    show_parser.add_argument('--hook', help='显示特定 Hook 配置')
    
    # 验证配置
    subparsers.add_parser('validate', help='验证配置')
    
    # 启用/禁用 Hook
    enable_parser = subparsers.add_parser('enable', help='启用 Hook')
    enable_parser.add_argument('hook_name', help='Hook 名称')
    
    disable_parser = subparsers.add_parser('disable', help='禁用 Hook')
    disable_parser.add_argument('hook_name', help='Hook 名称')
    
    # 添加任务
    add_task_parser = subparsers.add_parser('add-task', help='添加任务')
    add_task_parser.add_argument('hook_name', help='Hook 名称')
    add_task_parser.add_argument('--name', required=True, help='任务名称')
    add_task_parser.add_argument('--type', required=True, help='任务类型')
    add_task_parser.add_argument('--config', help='任务配置 (JSON 格式)')
    
    # 移除任务
    remove_task_parser = subparsers.add_parser('remove-task', help='移除任务')
    remove_task_parser.add_argument('hook_name', help='Hook 名称')
    remove_task_parser.add_argument('task_name', help='任务名称')
    
    # 设置全局配置
    set_global_parser = subparsers.add_parser('set-global', help='设置全局配置')
    set_global_parser.add_argument('key', help='配置键')
    set_global_parser.add_argument('value', help='配置值')
    
    # 导出/导入配置
    export_parser = subparsers.add_parser('export', help='导出配置')
    export_parser.add_argument('output_file', help='输出文件')
    
    import_parser = subparsers.add_parser('import', help='导入配置')
    import_parser.add_argument('input_file', help='输入文件')
    
    # 创建模板
    template_parser = subparsers.add_parser('create-template', help='创建配置模板')
    template_parser.add_argument('template_name', help='模板名称')
    
    args = parser.parse_args()
    
    if not args.command:
        parser.print_help()
        return
    
    manager = ConfigManager()
    
    if args.command == 'show':
        success = manager.show_config(args.hook)
    elif args.command == 'validate':
        success = manager.validate_config()
    elif args.command == 'enable':
        success = manager.enable_hook(args.hook_name)
    elif args.command == 'disable':
        success = manager.disable_hook(args.hook_name)
    elif args.command == 'add-task':
        task_config = {
            'name': args.name,
            'type': args.type,
            'config': json.loads(args.config) if args.config else {}
        }
        success = manager.add_task(args.hook_name, task_config)
    elif args.command == 'remove-task':
        success = manager.remove_task(args.hook_name, args.task_name)
    elif args.command == 'set-global':
        success = manager.set_global_config(args.key, args.value)
    elif args.command == 'export':
        success = manager.export_config(args.output_file)
    elif args.command == 'import':
        success = manager.import_config(args.input_file)
    elif args.command == 'create-template':
        success = manager.create_template(args.template_name)
    else:
        parser.print_help()
        return
    
    sys.exit(0 if success else 1)


if __name__ == "__main__":
    main()
